# LocalStack Resource Provider Scaffolding v2
from __future__ import annotations

import json
from pathlib import Path
from typing import Optional, TypedDict

from botocore.exceptions import ClientError

import localstack.services.cloudformation.provider_utils as util
from localstack.services.cloudformation.resource_provider import (
    OperationStatus,
    ProgressEvent,
    ResourceProvider,
    ResourceRequest,
)
from localstack.services.sns.models import create_default_sns_topic_policy


class SNSTopicPolicyProperties(TypedDict):
    PolicyDocument: Optional[dict | str]
    Topics: Optional[list[str]]
    Id: Optional[str]


REPEATED_INVOCATION = "repeated_invocation"


class SNSTopicPolicyProvider(ResourceProvider[SNSTopicPolicyProperties]):
    TYPE = "AWS::SNS::TopicPolicy"  # Autogenerated. Don't change
    SCHEMA = util.get_schema_path(Path(__file__))  # Autogenerated. Don't change

    def create(
        self,
        request: ResourceRequest[SNSTopicPolicyProperties],
    ) -> ProgressEvent[SNSTopicPolicyProperties]:
        """
        Create a new resource.

        Primary identifier fields:
          - /properties/Id

        Required properties:
          - PolicyDocument
          - Topics

        Read-only properties:
          - /properties/Id

        IAM permissions required:
          - sns:SetTopicAttributes

        """
        model = request.desired_state
        sns_client = request.aws_client_factory.sns

        policy = json.dumps(model["PolicyDocument"])
        for topic_arn in model["Topics"]:
            sns_client.set_topic_attributes(
                TopicArn=topic_arn, AttributeName="Policy", AttributeValue=policy
            )

        model["Id"] = util.generate_default_name(
            stack_name=request.stack_name, logical_resource_id=request.logical_resource_id
        )

        return ProgressEvent(
            status=OperationStatus.SUCCESS,
            resource_model=model,
            custom_context=request.custom_context,
        )

    def read(
        self,
        request: ResourceRequest[SNSTopicPolicyProperties],
    ) -> ProgressEvent[SNSTopicPolicyProperties]:
        """
        Fetch resource information


        """
        raise NotImplementedError

    def delete(
        self,
        request: ResourceRequest[SNSTopicPolicyProperties],
    ) -> ProgressEvent[SNSTopicPolicyProperties]:
        """
        Delete a resource

        IAM permissions required:
          - sns:SetTopicAttributes
        """
        model = request.desired_state
        sns = request.aws_client_factory.sns

        for topic_arn in model["Topics"]:
            try:
                sns.set_topic_attributes(
                    TopicArn=topic_arn,
                    AttributeName="Policy",
                    AttributeValue=json.dumps(create_default_sns_topic_policy(topic_arn)),
                )

            except ClientError as err:
                if "NotFound" not in err.response["Error"]["Code"]:
                    raise

        return ProgressEvent(
            status=OperationStatus.SUCCESS,
            resource_model=model,
            custom_context=request.custom_context,
        )

    def update(
        self,
        request: ResourceRequest[SNSTopicPolicyProperties],
    ) -> ProgressEvent[SNSTopicPolicyProperties]:
        """
        Update a resource

        IAM permissions required:
          - sns:SetTopicAttributes
        """
        raise NotImplementedError
